package com.example.controller;

import com.example.dao.UserCrudRepository;
import com.example.pojo.PageBean;
import com.example.pojo.User;
import com.example.tools.JwtUtils;
import com.example.tools.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserCrudRepository userCrudRepository;

    @PostMapping("/login")
    public Result Login(@RequestBody User user) {
        log.info("User:{}", user);
        User login = null;
        //身份证号登录
        login = userCrudRepository.loginByIdNumber(user.getIdNumber(), user.getPassword());
        //编号登录
        if (login == null) {
            login = userCrudRepository.loginById(Integer.parseInt(user.getIdNumber()), user.getPassword());
        }
        if(login==null){
            return Result.error("用户名或密码错误");
        }
        if(login.getStatus().equals("注册未审核")){
            return Result.error("注册未审核，请等待审核");
        }
        if (login != null) {
            HashMap<String, Object> claims = new HashMap<>();
            claims.put("id", login.getId());
            String jwt = JwtUtils.generateJwt(claims);//jwt包含了当前登录的员工信息
            return Result.success(jwt);
        }
        //登录失败，返回错误信息
        return Result.error("用户名或密码错误");
    }

    @GetMapping("/getInfo")
    public Result getInfo(@RequestHeader("token") String token) {
        Integer id = JwtUtils.parseJWT(token).get("id", Integer.class);
        Optional<User> user = userCrudRepository.findById(id);
        return Result.success(user.get());
    }


    @PostMapping("/addUser")
    public Result add(@RequestBody User user) {
        log.info("addUser:{}", user);
        User userByPhone = userCrudRepository.getUserByPhone(user.getPhone());
        if (userByPhone != null) {
            return Result.error("手机号已存在");
        }
        User userByIdNumber = userCrudRepository.getUserByIdNumber(user.getIdNumber());
        if (userByIdNumber != null) {
            return Result.error("身份证号已存在");
        }
        userCrudRepository.save(user);
         return Result.success(user);
    }
    //注册
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        log.info("register:{}", user);
        User userByPhone = userCrudRepository.getUserByPhone(user.getPhone());
        if (userByPhone != null) {
            return Result.error("手机号已存在");
        }
        User userByIdNumber = userCrudRepository.getUserByIdNumber(user.getIdNumber());
        if (userByIdNumber != null) {
            return Result.error("身份证号已存在");
        }
        user.setRole("学员");
        user.setStatus("注册未审核");
        userCrudRepository.save(user);
        return Result.success(user);
    }

    //为机构分配账户
    @PostMapping("/addUserForAgency")
    @Transactional
    public Result addUserForAgency(Integer agencyId, Integer firstNum, Integer secondNum, Integer thirdNum) {
        log.info("为编号为" + agencyId + "的机构分配：" + "管理员账户数量:" + firstNum + "个发布员账户数量:" + secondNum + "个审核员账户数量:" + thirdNum + "个");
        saveUsers(firstNum,"机构管理员",agencyId);
        saveUsers(secondNum,"发布人员",agencyId);
        saveUsers(thirdNum,"审核人员",agencyId);
        return Result.success();
    }
    private void saveUsers(Integer num,String role,Integer agencyId){
        for (Integer i = 0; i < num; i++) {
            User user = new User();
            user.setRole(role);
            user.setAgencyId(agencyId);
            user.setPassword("123456");
            user.setStatus("正常");
            userCrudRepository.save(user);
        }
    }

    @DeleteMapping("/deleteUser")
    @Transactional
    public Result delete(@RequestBody List<Integer> ids, @RequestHeader("token") String token) {
        Integer id = JwtUtils.parseJWT(token).get("id", Integer.class);
        User user = userCrudRepository.findById(id).get();
        log.info(user.getRole() + " " + user.getName() + "正在删除User信息");
        log.info("ids:{}", ids);
        for (Integer userId : ids) {
            User deleteUser = userCrudRepository.getUserById(userId);
            if (user.getRole().equals("超级管理员") && (!deleteUser.getRole().equals("超级管理员"))) {
                userCrudRepository.deleteById(userId);
            } else if (user.getRole().equals("机构管理员") && deleteUser.getRole().equals("学员")) {
                userCrudRepository.deleteById(userId);
            }else {
                return Result.error("没有权限");
            }
        }
        return Result.success("删除成功");

    }

    @PostMapping("/updateUser")
    public Result update(@RequestBody User user) {
        log.info("updateUser:{}", user);
        //审核通过
        if(user.getStatus().equals("注册未审核")){
            user.setStatus("正常");
        }
        userCrudRepository.save(user);
        return Result.success(user);
    }

    @PostMapping("/getAllUser")
    public Result getAllUser(
            @RequestBody User user,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestHeader("token") String token) {
        Integer id = JwtUtils.parseJWT(token).get("id", Integer.class);
        User whoDo = userCrudRepository.findById(id).get();
        log.info("whoDo:{}", whoDo);
        Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.Direction.ASC, "id");
        Page<User> userPage = userCrudRepository.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //获取条件对象
                Predicate predicate = cb.conjunction();
                //判断用户对象
                if (user != null) {
                    // 根据 user 的属性添加查询条件
                    if (user.getName() != null) {
                        predicate.getExpressions().add(cb.like(root.get("name"), "%" + user.getName() + "%"));
                    }
                    //机构管理员只能查询本机构的人员信息
                    if (whoDo.getRole().equals("机构管理员")) {
                        predicate.getExpressions().add(cb.equal(root.get("agencyId"), whoDo.getAgencyId()));
                    }
                    if (user.getRole() != null) {
                        predicate.getExpressions().add(cb.equal(root.get("role"), user.getRole()));
                    }
                    if (user.getStatus() != null) {
                        predicate.getExpressions().add(cb.equal(root.get("status"), user.getStatus()));
                    }
                }
                return predicate;
            }
        }, pageable);
        List<User> users = userPage.getContent();
        long elements = userPage.getTotalElements();
        return Result.success(new PageBean(elements, users));
    }

    //批量导入
    @PostMapping("/addUsers")
    @Transactional
    public Result addUsers(@RequestBody List<User> users) {
        log.info("addUser:{}", users);
        for (User user : users) {
           if(user.getPhone()!=null){
               User userByPhone = userCrudRepository.getUserByPhone(user.getPhone());
               if (userByPhone != null) {
                   continue;
               }
           }
           if(user.getIdNumber()!=null){
               User userByIdNumber = userCrudRepository.getUserByIdNumber(user.getIdNumber());
               if (userByIdNumber != null) {
                   continue;
               }
           }

            userCrudRepository.save(user);
        }

        return Result.success();
    }

}
